package com.share.module.sys.user.web;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.share.module.sys.user.dto.UserDTO;
import com.share.module.sys.user.dto.UserNameAndPasswordDTO;
import com.share.module.sys.user.entity.User;
import com.share.module.sys.user.service.UserService;
import com.share.module.sys.user.vo.DownloadUserVO;
import com.share.module.sys.user.vo.UserPageQueryPageQueryVO;
import com.stock.common.response.ApiResult;
import com.stock.mybatisplus.utils.PageUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author lijy
 * @since 2023-04-04
 */
@Tag(name = "用户管理", description = "用户注册、登录、增删改查及文件导入导出接口")
@RequestMapping("/user")
@Controller
public class UserController {

    @Resource
    private UserService userService;

    /**
     * http://127.0.0.1:8090/share/user/loginHtml
     */
    @RequestMapping("loginHtml")
    public String login() {
        return "login";
    }

    // 测试登录  ---- http://127.0.0.1:8090/share/user/doLogin?name=zhang&pwd=123456
    @PostMapping("doLogin")
    public String doLogin(String username, String password) {
        UserNameAndPasswordDTO user = new UserNameAndPasswordDTO();
        user.setUsername(username);
        user.setPassword(password);
        userService.login(user);
        return "stock/stockAdd";
    }

    @Operation(summary = "分页查询", description = "简单分页查询用户列表")
    @GetMapping("/page")
    @ResponseBody
    public ApiResult<PageUtils> findPage(UserPageQueryPageQueryVO vo) {
        PageUtils pageUtils =  userService.page(vo);
        return ApiResult.success(pageUtils);
    }

    @PostMapping("/register")
    @ResponseBody
    @Operation(summary = "注册", description = "用户注册接口")
    public ApiResult<?> register(@Parameter(description = "用户名和密码") @Valid @RequestBody UserNameAndPasswordDTO user) {
        userService.register(user);
        return ApiResult.success();
    }

    @PostMapping("/login")
    @Operation(summary = "登录", description = "用户登录接口")
    @ResponseBody
    public ApiResult<UserDTO> login(@Parameter(description = "用户名和密码") @Valid @RequestBody UserNameAndPasswordDTO user) {
        return ApiResult.success(userService.login(user));
    }

    @PostMapping
    @ResponseBody
    @Operation(summary = "保存或更新", description = "保存或更新用户信息")
    public ApiResult<Boolean> save(@Parameter(description = "用户实体") @Valid @RequestBody User user) {
        return ApiResult.success(userService.saveOrUpdate(user));
    }

    @PostMapping("/del/batch")
    @ResponseBody
    @Operation(summary = "批量删除", description = "批量删除用户")
    public ApiResult<Boolean> batchDel(@Parameter(description = "用户ID列表") @RequestBody List<Integer> ids) {
        return ApiResult.success(userService.removeByIds(ids));
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    @Operation(summary = "删除", description = "根据id删除用户")
    public ApiResult<Boolean> delete(@Parameter(description = "用户ID") @PathVariable Integer id) {
        return ApiResult.success(userService.removeById(id));
    }

    @GetMapping
    @ResponseBody
    @Operation(summary = "列表所有", description = "查询所有用户列表")
    public ApiResult<List<User>> findAll() {
        return ApiResult.success(userService.list());
    }

    @GetMapping("/{id}")
    @ResponseBody
    @Operation(summary = "根据id查询", description = "根据id查询用户详情")
    public ApiResult<User> findOne(@Parameter(description = "用户ID") @PathVariable Integer id) {
        return ApiResult.success(userService.getById(id));
    }

    @GetMapping("/username/{username}")
    @ResponseBody
    @Operation(summary = "根据用户名查找", description = "根据用户名查找用户")
    public ApiResult<User> findOne(@Parameter(description = "用户名") @PathVariable String username) {
        User one = userService.getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, username));
        return ApiResult.success(one);
    }

    /**
     * 文件上传
     * <p>1. 创建excel对应的实体对象
     * <p>2. 由于默认一行行的读取excel，所以需要创建excel一行一行的回调监听器，
     * <p>3. 直接读即可
     */
    @PostMapping("upload")
    @ResponseBody
    @Operation(summary = "文件上传", description = "批量导入用户Excel文件")
    public ApiResult<?> upload(@Parameter(description = "Excel文件") MultipartFile file) throws IOException {
        userService.upload(file, userService);
        return ApiResult.success();
    }

    /**
     * 文件下载（失败了会返回一个有部分数据的Excel）
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link DownloadUserVO}
     * <p>
     * 2. 设置返回的 参数
     * <p>
     * 3. 直接写，这里注意，finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
     */
    @GetMapping("download")
    @Operation(summary = "文件下载", description = "导出用户数据为Excel文件")
    public void download(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<User> list = userService.list();
        List<DownloadUserVO> data = list.stream().map(t -> {
            DownloadUserVO userData = new DownloadUserVO();
            userData.setUsername(t.getUsername());
            userData.setPassword(t.getPassword());
            userData.setNickname(t.getNickname());
            userData.setEmail(t.getEmail());
            userData.setPhone(t.getPhone());
            userData.setAddress(t.getAddress());
            userData.setCreateTime(t.getCreateDate());
            return userData;
        }).collect(Collectors.toList());
        EasyExcel.write(response.getOutputStream(), DownloadUserVO.class).sheet("模板").doWrite(data);
    }

}

